﻿using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Unread.App.Common;
using Unread.App.Views;
using Unread.BackgroundTasks;
using Unread.Business.Models;
using Unread.Business.Repositories.Interfaces;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Background;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Unread.App
{
    sealed partial class App : Application
    {
        private readonly IFeedRepository _feedRepository;
        private readonly SettingsCharmInitializer _settingsInitializer;

        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;

            Bootstrapper.Run();

            _feedRepository = ServicesFactory.GetInstance<IFeedRepository>();
            _settingsInitializer = new SettingsCharmInitializer();
        }

        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            var rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = await CreateRootFrame(args);
                Window.Current.Content = rootFrame;
            }

            var isSecondaryTileForFeed = (args.Arguments == "feed");
            if (isSecondaryTileForFeed)
                rootFrame.Navigate(typeof(FeedItemPage), new FeedItemIdentifier { FeedId = new Guid(args.TileId) });

            if (rootFrame.Content == null)
            {
                var loadState = (args.PreviousExecutionState == ApplicationExecutionState.Terminated);
                var extendedSplash = new ExtendedSplash(_feedRepository, args.SplashScreen, loadState);
                Window.Current.Content = extendedSplash;
            }

            Window.Current.Activate();

            await RegisterBackgroundTasks();
        }

        protected override void OnWindowCreated(WindowCreatedEventArgs args)
        {
            base.OnWindowCreated(args);

            SettingsPane.GetForCurrentView().CommandsRequested += _settingsInitializer.Initialize;
        }

        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();
            deferral.Complete();
        }

        private static async Task<Frame> CreateRootFrame(LaunchActivatedEventArgs args)
        {
            var rootFrame = new Frame();
            SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

            if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                try
                {
                    await SuspensionManager.RestoreAsync();
                }
                catch (SuspensionManagerException ex)
                {
                    //Something went wrong restoring state.
                    //Assume there is no state and continue
                    Debug.WriteLine(ex);
                }
            }

            return rootFrame;
        }

        private static async Task RegisterBackgroundTasks()
        {
            await RequestLockScreenAccess();

            var hourlyTrigger = new TimeTrigger(60, false);
            var internetAvailableCondition = new SystemCondition(SystemConditionType.InternetAvailable);
            var taskEntryPoint = typeof(NotificationBackgroundTask).FullName;
            
            BackgroundTaskRegistrar.RegisterBackgroundTask(taskEntryPoint, "NotificationBackgroundTask", hourlyTrigger, internetAvailableCondition);
        }

        private static async Task RequestLockScreenAccess()
        {
            try
            {
                await BackgroundExecutionManager.RequestAccessAsync();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
    }
}
